package org.jeecg.modules.fund.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ExecutorBuilder;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.fund.entity.StockLibrary;
import org.jeecg.modules.fund.entity.StockValue;
import org.jeecg.modules.fund.mapper.StockValueMapper;
import org.jeecg.modules.fund.service.IStockLibraryService;
import org.jeecg.modules.fund.service.IStockValueService;
import org.jeecg.modules.fund.util.StockValueUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;

@Slf4j
@Service
public class StockValueServiceImpl extends ServiceImpl<StockValueMapper, StockValue> implements IStockValueService {
    @Autowired
    private StockValueMapper stockValueMapper;
    @Autowired
    private IStockLibraryService stockLibraryService;

    // 表前缀
    public static final String TABLE_NAME_PREFIX = "stock_value_";

    @Override
    public String createTableName(String code) {
        // 截取代码后两位
        String nameCategory = code.substring(code.length() - 2);
        // 表名
        String name = TABLE_NAME_PREFIX + nameCategory;
        // 判断一下表是否存在，不存在则新建
        isExistTable(name);
        return name;
    }

    @Override
    public void isExistTable(String tableName) {
        try {
            // 判断净值表是否存在
            int isExist = stockValueMapper.isExistTable(tableName);
            // 表不存在，则新建
            if (isExist == 0) {
                stockValueMapper.createTable(tableName);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createAllStockValue()  {
        log.info("======= 执行【股票净值】同步任务");
        log.info("【股票净值】开始时间：" + DateUtil.now());
        // 线程池
        ExecutorService executorService = ExecutorBuilder.create()
                .setCorePoolSize(2)
                .setMaxPoolSize(2)
                .setWorkQueue(new LinkedBlockingQueue<>(400))
                .build();
        // 获取股票的类别
        List<StockLibrary> stockCategoryList = stockLibraryService.list(new QueryWrapper<StockLibrary>().select("RIGHT(code,2) as 'code'").groupBy("RIGHT(code,2)"));
        // 遍历类别
        for (int i = 0;i< stockCategoryList.size();i++){
            // TODO：为了便于测试，仅测试新增一个数据表
            if(i != 0){
                continue;
            }
            final int taskId = i;
            // 执行线程池
            executorService.submit(() -> {
                StockLibrary category = stockCategoryList.get(taskId);
                // 获取类别对应的数据
                List<StockLibrary> stockLibraryList = stockLibraryService.list(new QueryWrapper<StockLibrary>().eq("RIGHT(code,2)",category.getCode()));
                // 遍历子类别
                for (StockLibrary stockLibrary : stockLibraryList){
                    // 生成表名
                    String tableName = createTableName(stockLibrary.getCode());
                    // 从远程获取数据
                    JSONArray httpData = StockValueUtil.getHttpData(stockLibrary.getCode());
                    if(httpData != null && !httpData.isEmpty()){
                        List<StockValue> valueList = new ArrayList<>();
                        httpData.forEach(item -> {
                            JSONObject data = JSONObject.parseObject(item.toString());
                            StockValue stockValue = new StockValue()
                                    .setId(data.getString("股票代码") + "-" + DateUtil.format(data.getDate("日期"),"yyyyMMdd"))
                                    .setCode(data.getString("股票代码"))
                                    .setVal(data.getBigDecimal("收盘"))
                                    .setVolume(data.getBigDecimal("涨跌额"))
                                    .setRate(data.getBigDecimal("涨跌幅"))
                                    .setOpen(data.getBigDecimal("开盘"))
                                    .setHigh(data.getBigDecimal("最高"))
                                    .setLow(data.getBigDecimal("最低"))
                                    .setZf(data.getBigDecimal("振幅"))
                                    .setTradeDate(data.getDate("日期"));
                            valueList.add(stockValue);
                        });
                        if(!valueList.isEmpty()){
                            stockValueMapper.batchInsertOrUpdate(tableName,valueList);
                            if(taskId == stockCategoryList.size() - 1){
                                log.info("【股票净值】结束时间：" + DateUtil.now());
                            }
                        }
                    }
                }
            });
        }
        executorService.shutdown();
    }
}
